/*************************************
* Base Class for Command
***/
class Command
{
public:
	virtual bool Execute() = 0;
	virtual bool UnExecute() {return false;}
	bool IsReversible(){return isReversible;}
protected:
	bool isReversible;
};

/*************************************
 * Base Class for CommandSeries
 ***/
class CommandSeries : public Command
{
public:
	virtual bool UnExecute();
protected:
	LinkedList<Command*> CmdList;
};

///////////////////////////////////////////////////////
/* Class for Commands */

/* Open and Save*/
class OpenCommand : public Command
{
public:
	void Init(OpenBuilder* Builder);
	virtual bool Execute() {return currentBuilder->Open();}
	OpenCommand() {isReversible = false;}
protected:
	OpenBuilder* currentBuilder;
};

class SaveCommand : public Command
{
public:
	void Init(SaveBuilder* Builder);
	virtual bool Execute(){return currentBuilder->Save();}
	SaveCommand() {isReversible = false;}
protected:
	SaveBuilder* currentBuilder;
};

/* Write in Cell */
class WriteCommand : public Command
{
public:
	void Init(const CELLPOS & pos, const wstring & str, Sheet* psht, bool Remove = false);
	virtual bool Execute();
	virtual bool UnExecute();
	WriteCommand(){isReversible = true;}
protected:
	wstring	strToWrite;
	Sheet*			pSheet;
	CELLPOS			cellPosition;
	bool			removeCell;
	MemState		memState;	// the state at the time when command is not executed
};

/* Change Height of Row */
class ChangeRowHeightCmd : public Command
{
public:
	void Init(const int NewHeight, ROW_NUM iRow, Sheet* psht);
	virtual bool Execute();
	virtual bool UnExecute();
	ChangeRowHeightCmd(){isReversible = true;}
protected:
	Sheet*		pSheet;
	ROW_NUM		iRow;
	int			oldHeight;
	int			newHeight;
};

/* Change Width of Col*/
class ChangeColWidthCmd : public Command
{
public:
	void Init(const int NewWidth, COL_NUM iCol, Sheet* psht);
	virtual bool Execute();
	virtual bool UnExecute();
	ChangeColWidthCmd(){isReversible = true;}
protected:
	Sheet*		pSheet;
	COL_NUM		iCol;
	int			oldWidth;
	int			newWidth;
};

/* Insert a Row */
class InsertRowCmd : public Command
{
public:
	void Init(const ROW_NUM iRow, Sheet* psht);
	virtual bool Execute();
	virtual bool UnExecute();
	InsertRowCmd(){isReversible = true;}
protected:
	Sheet*	pSheet;
	ROW_NUM	iRow;
};

/* Insert a Col */
class InsertColCmd : public Command
{
public:
	void Init(const COL_NUM iCol, Sheet* psht);
	virtual bool Execute();
	virtual bool UnExecute();
	InsertColCmd(){isReversible = true;}
protected:
	Sheet* pSheet;
	COL_NUM iCol;
};

/* Delete a Row */
class RemoveRowCmd : public CommandSeries
{
public:
	void Init(const ROW_NUM irow, Sheet* psht);
	virtual bool Execute();
	virtual bool UnExecute();
	RemoveRowCmd(){isReversible = true;}
protected:
	Sheet*	pSheet;
	ROW_NUM iRow;
};

/* Delete a Col */
class RemoveColCmd : public CommandSeries
{
public:
	void Init(const COL_NUM icol, Sheet* psht);
	virtual bool Execute();
	virtual bool UnExecute();
	RemoveColCmd(){isReversible = true;}
protected:
	Sheet*	pSheet;
	COL_NUM iCol;
};

/* Delete Region*/
class DeleteRegionCmd : public CommandSeries
{
public:
	void Init(const CELLPOS& start, const CELLPOS& end, Sheet* psht);
	virtual bool Execute();
	DeleteRegionCmd(){isReversible = true;}
protected:
	Sheet* pSheet;
	ROW_NUM iRow_s, iRow_e;
	COL_NUM iCol_s, iCol_e;
};

/* Set Color of Single Cell */
class SetSingleColorCmd : public Command
{
public:
	void Init(const CELLPOS& pos, const COLORREF& color, ModifiedField MF, Sheet* psht);
	virtual bool Execute();
	virtual bool UnExecute();
	SetSingleColorCmd(){isReversible = true;}
protected:
	Sheet*			pSheet;
	CELLPOS			cellPosition;
	MemState		mem;
	COLORREF		newColor;
	ModifiedField	mf;
};

/* Set Color of Multi Cell */
class SetColorCmd : public CommandSeries
{
public:
	void Init(const CELLPOS& start, const CELLPOS& end, const COLORREF& color, ModifiedField MF, Sheet* psht, bool clear = false);
	virtual bool Execute();
	SetColorCmd(){isReversible = true;}
protected:
	Sheet*			pSheet;
	ROW_NUM iRow_s, iRow_e;
	COL_NUM iCol_s, iCol_e;
	ModifiedField	mf;
	COLORREF		newColor;
	bool			isClearColor;
};

/* Set Alignment of a single cell*/
class SetSingleAlignCmd : public Command
{
public:
	void Init(const CELLPOS& pos, const UINT& align, ModifiedField MF, Sheet* psht);
	virtual bool Execute();
	virtual bool UnExecute();
	SetSingleAlignCmd(){isReversible = true;}
protected:
	Sheet*			pSheet;
	CELLPOS			cellPosition;
	MemState		mem;
	UINT			newAlign;
	ModifiedField	mf;
};

/* Set Alignment of Multi Cell */
class SetAlignCmd : public CommandSeries
{
public:
	void Init(const CELLPOS& start, const CELLPOS& end, const UINT& align, ModifiedField MF, Sheet* psht);
	virtual bool Execute();
	SetAlignCmd(){isReversible = true;}
protected:
	Sheet*			pSheet;
	ROW_NUM iRow_s, iRow_e;
	COL_NUM iCol_s, iCol_e;
	ModifiedField	mf;
	INT				newAlign;
};

/* Copy */
class CopyRegionCmd : public Command
{
public:
	void Init(const CELLPOS& start, const CELLPOS& end, Sheet* psht);
	virtual bool Execute();
	CopyRegionCmd(){isReversible = false;}
protected:
	Sheet* pSheet;
	ROW_NUM iRow_s, iRow_e;
	COL_NUM iCol_s, iCol_e;
};

class PasteCmd: public CommandSeries
{
public:
	void Init(const CELLPOS& Pos, Sheet* psht);
	virtual bool Execute();
	PasteCmd(){isReversible = true;}
private:
	Sheet* pSheet;
	ROW_NUM iRow;
	COL_NUM iCol;
};

/* Set FontAttr of a single cell*/
class SetSingleFontAttrCmd : public Command
{
public:
	void Init(const CELLPOS& pos, const UINT& attr, ModifiedField MF, Sheet* psht);
	virtual bool Execute();
	virtual bool UnExecute();
	SetSingleFontAttrCmd(){isReversible = true;}
protected:
	Sheet*			pSheet;
	CELLPOS			cellPosition;
	MemState		mem;
	UINT			attr;
	ModifiedField	mf;
};

/* Set FontAttr of Multi Cell */
class SetFontAttrCmd : public CommandSeries
{
public:
	void Init(const CELLPOS& start, const CELLPOS& end, const UINT& attr, ModifiedField MF, Sheet* psht);
	virtual bool Execute();
	SetFontAttrCmd(){isReversible = true;}
protected:
	Sheet*			pSheet;
	ROW_NUM iRow_s, iRow_e;
	COL_NUM iCol_s, iCol_e;
	ModifiedField	mf;
	INT				attr;
};

/* Set Font of a single cell*/
class SetSingleFontCmd : public Command
{
public:
	void Init(const CELLPOS& pos, const UINT& attr, const wstring& fontName, ModifiedField MF, Sheet* psht);
	virtual bool Execute();
	virtual bool UnExecute();
	SetSingleFontCmd(){isReversible = true;}
protected:
	Sheet*			pSheet;
	CELLPOS			cellPosition;
	MemState		mem;
	UINT			attr;
	wstring			newFontName;
	ModifiedField	mf;
	SetSingleFontAttrCmd AttrCmd;
};

/* Set FontAttr of Multi Cell */
class SetFontCmd : public CommandSeries
{
public:
	void Init(const CELLPOS& start, const CELLPOS& end, const UINT& attr, PTSTR fontName, ModifiedField MF, Sheet* psht);
	virtual bool Execute();
	SetFontCmd(){isReversible = true;}
protected:
	Sheet*			pSheet;
	ROW_NUM iRow_s, iRow_e;
	COL_NUM iCol_s, iCol_e;
	ModifiedField	mf;
	UINT				attr;
	wstring			newFontName;
};